/**
 * 日期格式转换工具
 * 支持多种日期格式的解析和转换
 * 统一输出为英文格式："Jun 05, 2025"
 */

const { log } = require('../utils.js');

/**
 * 月份映射表
 */
const MONTH_NAMES = {
    // 英文月份缩写
    'Jan': 0, 'Feb': 1, 'Mar': 2, 'Apr': 3, 'May': 4, 'Jun': 5,
    'Jul': 6, 'Aug': 7, 'Sep': 8, 'Oct': 9, 'Nov': 10, 'Dec': 11,
    
    // 英文月份全称
    'January': 0, 'February': 1, 'March': 2, 'April': 3, 'May': 4, 'June': 5,
    'July': 6, 'August': 7, 'September': 8, 'October': 9, 'November': 10, 'December': 11,
    
    // 中文月份
    '一月': 0, '二月': 1, '三月': 2, '四月': 3, '五月': 4, '六月': 5,
    '七月': 6, '八月': 7, '九月': 8, '十月': 9, '十一月': 10, '十二月': 11,
    
    // 数字月份（字符串）
    '01': 0, '02': 1, '03': 2, '04': 3, '05': 4, '06': 5,
    '07': 6, '08': 7, '09': 8, '10': 9, '11': 10, '12': 11,
    
    '1': 0, '2': 1, '3': 2, '4': 3, '5': 4, '6': 5,
    '7': 6, '8': 7, '9': 8, '10': 9, '11': 10, '12': 11
};

/**
 * 输出月份名称数组
 */
const OUTPUT_MONTHS = [
    'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
    'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'
];

/**
 * 日期格式正则表达式模式
 */
const DATE_PATTERNS = [
    // ISO 8601 格式：2025-06-05, 2025-06-05T10:30:00Z
    {
        pattern: /^(\d{4})-(\d{1,2})-(\d{1,2})(?:[T\s](\d{1,2}):(\d{1,2}):(\d{1,2})(?:\.\d{3})?(?:Z|[+-]\d{2}:\d{2})?)?$/,
        parser: (match) => new Date(parseInt(match[1]), parseInt(match[2]) - 1, parseInt(match[3]))
    },
    
    // 美式格式：06/05/2025, 6/5/2025, 06-05-2025
    {
        pattern: /^(\d{1,2})[\/-](\d{1,2})[\/-](\d{4})$/,
        parser: (match) => new Date(parseInt(match[3]), parseInt(match[1]) - 1, parseInt(match[2]))
    },
    
    // 欧式格式：05/06/2025, 5/6/2025, 05-06-2025
    {
        pattern: /^(\d{1,2})[\/-](\d{1,2})[\/-](\d{4})$/,
        parser: (match) => new Date(parseInt(match[3]), parseInt(match[2]) - 1, parseInt(match[1]))
    },
    
    // 英文格式：June 5, 2025, Jun 5, 2025
    {
        pattern: /^([A-Za-z]+)\s+(\d{1,2}),?\s+(\d{4})$/,
        parser: (match) => {
            const monthIndex = MONTH_NAMES[match[1]];
            if (monthIndex !== undefined) {
                return new Date(parseInt(match[3]), monthIndex, parseInt(match[2]));
            }
            return null;
        }
    },
    
    // 带星期几的英文格式：Thursday, July 24, 2025
    {
        pattern: /^\w+,\s+([A-Za-z]+)\s+(\d{1,2}),\s+(\d{4})$/,
        parser: (match) => {
            const monthIndex = MONTH_NAMES[match[1]];
            if (monthIndex !== undefined) {
                return new Date(parseInt(match[3]), monthIndex, parseInt(match[2]));
            }
            return null;
        }
    },
    
    // 英文格式：5 June 2025, 05 Jun 2025
    {
        pattern: /^(\d{1,2})\s+([A-Za-z]+)\s+(\d{4})$/,
        parser: (match) => {
            const monthIndex = MONTH_NAMES[match[2]];
            if (monthIndex !== undefined) {
                return new Date(parseInt(match[3]), monthIndex, parseInt(match[1]));
            }
            return null;
        }
    },
    
    // 中文格式：2025年6月5日
    {
        pattern: /^(\d{4})年(\d{1,2})月(\d{1,2})日$/,
        parser: (match) => new Date(parseInt(match[1]), parseInt(match[2]) - 1, parseInt(match[3]))
    },
    
    // 点分格式：05.06.2025, 5.6.2025
    {
        pattern: /^(\d{1,2})\.(\d{1,2})\.(\d{4})$/,
        parser: (match) => new Date(parseInt(match[3]), parseInt(match[2]) - 1, parseInt(match[1]))
    },
    
    // 紧凑格式：20250605
    {
        pattern: /^(\d{4})(\d{2})(\d{2})$/,
        parser: (match) => new Date(parseInt(match[1]), parseInt(match[2]) - 1, parseInt(match[3]))
    },
    
    // Unix时间戳（秒）
    {
        pattern: /^\d{10}$/,
        parser: (match) => new Date(parseInt(match[0]) * 1000)
    },
    
    // Unix时间戳（毫秒）
    {
        pattern: /^\d{13}$/,
        parser: (match) => new Date(parseInt(match[0]))
    },
    
    // 相对日期：今天、昨天、明天
    {
        pattern: /^(今天|昨天|明天|today|yesterday|tomorrow)$/i,
        parser: (match) => {
            const today = new Date();
            const word = match[0].toLowerCase();
            if (word === '今天' || word === 'today') {
                return today;
            } else if (word === '昨天' || word === 'yesterday') {
                return new Date(today.getTime() - 24 * 60 * 60 * 1000);
            } else if (word === '明天' || word === 'tomorrow') {
                return new Date(today.getTime() + 24 * 60 * 60 * 1000);
            }
            return null;
        }
    }
];

/**
 * 尝试解析日期字符串
 * @param {string} dateString - 待解析的日期字符串
 * @returns {Date|null} - 解析成功返回Date对象，失败返回null
 */
function parseDate(dateString) {
    if (!dateString || typeof dateString !== 'string') {
        return null;
    }
    
    const trimmed = dateString.trim();
    if (!trimmed) {
        return null;
    }
    
    // 尝试各种格式模式
    for (const { pattern, parser } of DATE_PATTERNS) {
        const match = trimmed.match(pattern);
        if (match) {
            try {
                const date = parser(match);
                if (date && !isNaN(date.getTime())) {
                    return date;
                }
            } catch (error) {
                // 继续尝试下一个模式
                continue;
            }
        }
    }
    
    // 最后尝试JavaScript原生Date构造函数
    try {
        const date = new Date(trimmed);
        if (!isNaN(date.getTime())) {
            return date;
        }
    } catch (error) {
        // 忽略错误
    }
    
    return null;
}

/**
 * 将日期格式化为英文格式："Jun 05, 2025"
 * @param {Date} date - Date对象
 * @returns {string} - 格式化后的日期字符串
 */
function formatToEnglish(date) {
    if (!date || isNaN(date.getTime())) {
        return '';
    }
    
    const month = OUTPUT_MONTHS[date.getMonth()];
    const day = String(date.getDate()).padStart(2, '0');
    const year = date.getFullYear();
    
    return `${month} ${day}, ${year}`;
}

/**
 * 主要的日期转换函数
 * @param {string} dateString - 待转换的日期字符串
 * @param {boolean} enableLogging - 是否启用日志记录，默认true
 * @returns {string} - 转换后的英文格式日期，失败时返回原字符串
 */
function formatDateToEnglish(dateString, enableLogging = true) {
    // 空值检查
    if (!dateString || (typeof dateString === 'string' && dateString.trim() === '')) {
        return '';
    }
    
    // 如果已经是目标格式，直接返回
    const targetPattern = /^[A-Za-z]{3}\s+\d{2},\s+\d{4}$/;
    if (targetPattern.test(dateString.trim())) {
        return dateString.trim();
    }
    
    try {
        const parsedDate = parseDate(dateString);
        
        if (parsedDate) {
            const formatted = formatToEnglish(parsedDate);
            if (enableLogging && formatted !== dateString.trim()) {
                log(`日期转换成功: "${dateString}" -> "${formatted}"`, 'info');
            }
            return formatted;
        } else {
            if (enableLogging) {
                log(`无法解析日期格式: "${dateString}"，保留原始值`, 'warning');
            }
            return dateString; // 返回原始字符串
        }
        
    } catch (error) {
        if (enableLogging) {
            log(`日期转换错误: ${error.message}, 原始日期: "${dateString}"`, 'error');
        }
        return dateString; // 返回原始字符串
    }
}

/**
 * 批量转换日期数组
 * @param {string[]} dateStrings - 日期字符串数组
 * @param {boolean} enableLogging - 是否启用日志记录，默认false
 * @returns {string[]} - 转换后的日期数组
 */
function formatDatesArrayToEnglish(dateStrings, enableLogging = false) {
    if (!Array.isArray(dateStrings)) {
        return [];
    }
    
    return dateStrings.map(dateString => formatDateToEnglish(dateString, enableLogging));
}

/**
 * 验证日期字符串是否为有效日期
 * @param {string} dateString - 待验证的日期字符串
 * @returns {boolean} - 是否为有效日期
 */
function isValidDate(dateString) {
    const parsedDate = parseDate(dateString);
    return parsedDate !== null && !isNaN(parsedDate.getTime());
}

/**
 * 获取支持的日期格式示例
 * @returns {string[]} - 支持的日期格式示例数组
 */
function getSupportedFormats() {
    return [
        '2025-06-05',
        '2025-06-05T10:30:00Z',
        '06/05/2025',
        '6/5/2025',
        '06-05-2025',
        '05/06/2025 (欧式)',
        '5/6/2025 (欧式)',
        'June 5, 2025',
        'Jun 5, 2025',
        '5 June 2025',
        '05 Jun 2025',
        '2025年6月5日',
        '05.06.2025',
        '5.6.2025',
        '20250605',
        '1735689600 (Unix秒)',
        '1735689600000 (Unix毫秒)',
        '今天/昨天/明天',
        'today/yesterday/tomorrow'
    ];
}

module.exports = {
    formatDateToEnglish,
    formatDatesArrayToEnglish,
    isValidDate,
    getSupportedFormats,
    parseDate,
    formatToEnglish
};